<template>
  <div :style="{left: left + 'px', top: top + 'px'}" @mousedown="onMousedown" class="drag">
    <slot></slot>
  </div>
</template>

<script>
export default {
  props: {
    // 允许拖拽的方向 x: 左右 y: 上下
    dir: {
      type: String,
      default: "xy" // 允许上下左右拖拽
    },
    rect: {
      type: Array,
      default: function() {
        // 数组中 上 下 左 右
        // -1: 不限制
        return [-1, -1, -1, -1];
      }
    }
  },
  data() {
    return {
      left: 0, // 元素左上角x坐标
      top: 0, // 元素左上角y坐标
      leftDelta: 0, // 鼠标在元素中的 x 坐标
      topDelta: 0, // 鼠标在元素中的 y 坐标
      isClicking: false // 当前是否正在点着元素
    };
  },
  mounted() {
    // 鼠标移动事件
    document.addEventListener("mousemove", this.onMousemove);
    // 鼠标放开事件
    document.addEventListener("mouseup", this.onMouseup);
  },
  methods: {
    // 当鼠标点击时
    onMousedown(e) {
      // console.log(e)
      this.isClicking = true;
      // 计算鼠标在点击时的元素中的位置: 鼠标位置 - 元素位置
      this.leftDelta = e.pageX - this.left;
      this.topDelta = e.pageY - this.top;
      // console.log(this.topDelta)
      // console.log(this.leftDelta)
    },
    // 当松开鼠标时
    onMouseup() {
      this.isClicking = false;
    },
    // 当按下鼠标移动时
    onMousemove(e) {
      // 如果当前点击着元素 那么就让元素跟着鼠标动
      // pageX pageY (鼠标的位置 （含滚动条）)
      if (this.isClicking) {
        // 是否允许左右移动 (判断 dir 属性中 是否 包含 x 字符 )
        if (this.dir.includes("x")) {
          // 判断是否有 左 右 限制
          if (this.rect[2] !== -1) {
            // 计算移动的位置
            let left = e.pageX - this.leftDelta
            // console.log(left)
            if (left >= this.rect[2] && left <= this.rect[3]) {
              this.left = left
            }
          } else {
            this.left = e.pageX - this.leftDelta
            // console.log(this.left)
          }
        }

        // 是否允许上下移动 (判断 dir 属性中 是否 包含 y 字符 )
        if (this.dir.includes("y")) {
          // 判断是否有 上 下 限制
          if ( this.rect[0] !== -1) {
            // 计算移动位置
            let top = e.pageY - this.topDelta
            if (top >= this.rect[0] && top <= this.rect[1]) {
              this.top = top
            }
          } else {
            this.top = e.pageY - this.topDelta
          }
        }
        // 将移动之后的当前位置发送给父组件
        this.$emit("move", {
          left: this.left,
          top: this.top
        })
      }
    }
  }
};
</script>

<style lang="scss">
.drag {
  position: absolute;
  z-index: 9999;
  cursor: pointer;
}
</style>